package com.quwan.app.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.quwan.anno.AccessCount;
import com.quwan.anno.UpdateAccessTime;
import com.quwan.app.service.BannerService;
import com.quwan.app.service.MemberService;
import com.quwan.app.service.OrderService;
import com.quwan.app.service.ProductCategoryService;
import com.quwan.app.vo.*;
import com.quwan.chat.properties.NettyProperties;
import com.quwan.common.BaseController;
import com.quwan.common.ImMsgType;
import com.quwan.common.enums.CommonStatus;
import com.quwan.common.enums.SystemMsgEnum;
import com.quwan.common.result.ApiResult;
import com.quwan.common.result.MsgCallBackResp;
import com.quwan.common.result.PageResult;
import com.quwan.component.ComponentFactory;
import com.quwan.component.TencentComponent;
import com.quwan.config.yml.AppAlipayConfig;
import com.quwan.config.yml.ImConfig;
import com.quwan.config.yml.WebViewConfig;
import com.quwan.entity.*;
import com.quwan.manager.service.MemberLevelService;
import com.quwan.mapper.TAppVersionMapper;
import com.quwan.mapper.TCommentTagMapper;
import com.quwan.mapper.TMessageAccountMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author quan
 * @date 2021-06-09 14:50
 */
@Api(tags = "App")
@RestController
@RequestMapping("app")
@RequiredArgsConstructor
@Validated
public class AppController extends BaseController {
    public static boolean SPREADSETTINGOFF = false;

    private final BannerService bannerService;
    private final ProductCategoryService productCategoryService;
    private final OrderService orderService;
    private final NettyProperties nettyProperties;
    private final MemberService memberService;
    private final TencentComponent tencentComponent;
    private final TCommentTagMapper commentTagMapper;
    private final TMessageAccountMapper messageAccountMapper;
    private final MemberLevelService levelService;
    private final AppAlipayConfig appAlipayConfig;
    private final WebViewConfig webViewConfig;
    private final ComponentFactory componentFactory;
    private final TAppVersionMapper versionMapper;
    private final ImConfig imConfig;
    private static final BigDecimal def_lat = new BigDecimal("30.659462");
    private static final BigDecimal def_lng = new BigDecimal("104.051666");

    @UpdateAccessTime
    @ApiOperation(value = "app首页分类栏目 banner栏目数据", notes = "<span style=\"color:red\">注意参数是否必填,返回数据中" +
            "</br>banner(轮播栏目数据):[id——轮播元素主键;title——轮播标题;\n</br>" +
            " category =1 跳转h5连接 \n category=2跳转app内部路径  action=android路径  actionPath=ios路径 " +
            ";imageUrl——图片地址;] " +
            "category(技能服务分类数据)[id——服务技能分类id;caption——标题;orderNum——排序;showColor——展示颜色;icon——图标]" +
            "</span>")
    @GetMapping("index")
    public ApiResult<Map> appIndex() {
        Map<String, Object> res = new HashMap<>();
        res.put("category", productCategoryService.getAppIndexOwner());
        res.put("banner", bannerService.getShowIndexBanner());
        return ApiResult.success(res);

    }

    @UpdateAccessTime
    @ApiOperation(value = "app首页分类栏目 banner栏目数据", notes = "<span style=\"color:red\">注意参数是否必填,返回数据中" +
            "</br>banner(轮播栏目数据):[id——轮播元素主键;title——轮播标题;\n</br>" +
            " category =1 跳转h5连接 \n category=2跳转app内部路径  action=android路径  actionPath=ios路径 " +
            ";imageUrl——图片地址;] " +
            "category(技能服务分类数据)[id——服务技能分类id;caption——标题;orderNum——排序;showColor——展示颜色;icon——图标]" +
            "</span>")
    @GetMapping("index2.6.2")
    public ApiResult<IndexData> appIndex2New() {

        IndexData res = new IndexData();
        res.setBanner(bannerService.getShowIndexBanner())
                .setCategory(productCategoryService.getAppIndexOwnerNew() );

        return ApiResult.success(res);

    }


    @ApiOperation(value = "推广配置开关")
    @PostMapping("spreadSettingOff")
    public ApiResult<Boolean> spreadSettingOff() {

        return ApiResult.success(SPREADSETTINGOFF);

    }

    @ApiOperation(value = "app首页订单数据列表(关注)")
    @PostMapping("followOrderList")
    public ApiResult<PageResult<PublishOrderSimple>> appIndex(HttpServletRequest request,
                                                              @RequestParam int pageNo,
                                                              @RequestParam int pageSize,
                                                              @ApiParam("会员id") String mId) {
        if (StringUtils.isBlank(mId)) {
            try {
                mId = getId(request);
            } catch (Exception e) {
            }
        }
        logger.info("mid::{}", mId);
        checkPageSize(pageSize);
        return ApiResult.success(orderService.appPublishOrderList(pageNo, pageSize, mId));

    }

    @AccessCount
    @ApiOperation(value = "app首页订单数据列表")
    @PostMapping("orderList")
    public ApiResult<PageResult<PublishOrderSimple>> appIndex(@RequestParam int pageNo,
                                                              @RequestParam int pageSize,
                                                              @ApiParam("纬度") @RequestParam(required = false) BigDecimal lat,
                                                              @ApiParam("经度") @RequestParam(required = false) BigDecimal lng,
                                                              @ApiParam("分类筛选 非必须") @RequestParam(required = false) String categoryId,
                                                              @ApiParam("一级分类筛选 非必须") @RequestParam(required = false) String parentCate,
                                                              @ApiParam("0同城数据,1推荐数据") @RequestParam(required = false) String type,
                                                              @ApiParam("0智能排序 1 最新发布 2距离最近") @RequestParam(required = false) String auto,
                                                              @ApiParam("价格筛选 1 倒叙 2 正序") @RequestParam(required = false) String price,
                                                              @ApiParam("年龄筛选  传值") @RequestParam(required = false) Integer age,
                                                              @ApiParam("城市") @RequestParam(value = "cn", required = false) String cityName,
                                                              @ApiParam("城市代码") @RequestParam(value = "cc", required = false) String cityCode,
                                                              @ApiParam("性别筛选 0只看女,1只看男") @RequestParam(value = "gender", required = false) String gender,
                                                              @ApiParam("词条搜索") @RequestParam(value = "keyword", required = false) String keyword
    ) {
        if (lat == null || lng == null) {
            lat = def_lat;
            lng = def_lng;
        }
        checkPageSize(pageSize);
        return ApiResult.success(orderService.appPublishOrderList(pageNo, pageSize, lat, lng, categoryId, type, auto, price, age, cityName, cityCode, gender,parentCate,keyword));

    }

    @AccessCount
    @UpdateAccessTime
    @ApiOperation("订单信息")
    @PostMapping("publishOrderDetail")
    public ApiResult<PublishOrderSimple> publishOrderDetail(HttpServletRequest request,
                                                            @ApiParam("发布订单Id") @NotBlank @RequestParam String publishOrderId) {
        String mId = "";
        try {
            mId = getId(request);
        } catch (Exception e) {
        }
        return ApiResult.success(orderService.getPublishOrderDetails(mId, publishOrderId));
    }

    @ApiOperation("搜索会员")
    @PostMapping("sm")
    public ApiResult<SearchMemberVo> searchMember(HttpServletRequest request,
                                                  @RequestParam @ApiParam("id|昵称") String kw,
                                                  @ApiParam("游客登录无token 需传id") @RequestParam(required = false) String mId) {
        try {
            mId = getId(request);
        } catch (Exception e) {
        }
        return ApiResult.success(memberService.search(mId, kw));

    }

    @Deprecated
    @ApiOperation("消息(聊天界面)")
    @PostMapping()
    public String chat() throws UnknownHostException {
        return "ws 连接：ws://" + InetAddress.getLocalHost().getHostAddress() + ":" + nettyProperties.getPort() + nettyProperties.getPath() +
                "\n数据格式：json" +
                "\n请求参数：" +
                "\n{\n" +
                "\"connectId\":10001,(建立连接用户id)\n" +
                "\"senderId\":10001,(发送消息用户id)\n" +
                "\"receiverId\":10002,(接收消息用户id)\n" +
                "\"content\":\"hello \",(消息内容)\n" +
                "\"type\":0,(连接事件 0代表用户是连接操作(connectId 必须)1代表是用户互动聊天(senderId receiverId content sessionId 必须))\n" +
                "\"sessionId\":\"1000110002\"(sessionId(会话Id)对应页面窗体id)\n" +
                "}" +
                "\n响应参数：" +
                "\ntype：0 用户建立连接如果有离线消息 返回数组形式 type:1 json ";

    }

    //@UpdateAccessTime
    @ApiOperation("im userSig")
    @PostMapping("im/userSig")
    public ApiResult<String> userSig(HttpServletRequest request) {
        return ApiResult.success(tencentComponent.createUserSig(getId(request)));
    }

    //@UpdateAccessTime
    @AccessCount
    @ApiOperation("im 消息未读数")
    @PostMapping("im/unread")
    public ApiResult<String> unread(HttpServletRequest request) {
        return ApiResult.success(tencentComponent.getUnreadMsgCount(getId(request)));
    }

    @ApiOperation("获取消息推送类型id")
    @GetMapping("mesAcc")
    public ApiResult<List<MessageAccDTO>> messageAccount() {
        return ApiResult.success(
                messageAccountMapper
                        .selectList(
                                new LambdaQueryWrapper<TMessageAccount>()
                                        .select(TMessageAccount::getAccount, TMessageAccount::getType)
                                        .eq(TMessageAccount::getStatus, 1)
                        )
                        .stream()
                        .map(m -> new MessageAccDTO().setAcc(m.getAccount()).setType(m.getType()))
                        .collect(Collectors.toList()));

    }

    @ApiOperation("评论标签")
    @GetMapping("ctag")
    public ApiResult<Set<String>> getCommentTag() {
        int pageNo = System.currentTimeMillis() % 2 == 0 ? 1 : 2;
        Page<Object> page = new Page<>(pageNo, 10);

        return ApiResult.success(
                commentTagMapper
                        .selectList(
                                new LambdaQueryWrapper<TCommentTag>()
                                        .select(TCommentTag::getTag))
                        .stream()
                        .map(TCommentTag::getTag)
                        .collect(Collectors.toSet()));
    }

    @ApiOperation("用户等级字典 key = 级别 value = TMemberLevel")
    @GetMapping("mlevel")
    public ApiResult<Map<Integer, TMemberLevel>> memberLevelList() {
        return ApiResult.success(Maps.uniqueIndex(levelService.getMemberLevelList(), TMemberLevel::getMLevel));

    }

    @ApiOperation("zfb授权url")
    @GetMapping("alioauth")
    public ApiResult aliOauthUrl() {
        HashMap<String, String> res = Maps.newHashMap();
        res.put("url", appAlipayConfig.getOauthUrl().replace("STATE", UUID.randomUUID().toString()));
        return ApiResult.success(res);

    }

    @ApiOperation(value = "协议", notes = "userAgree -用户协议  companyPolicy -  政策")
    @GetMapping("agree")
    public ApiResult agree() {
        HashMap<String, String> res = Maps.newHashMap();
        res.put("userAgree", webViewConfig.getUserAgree());
        res.put("companyPolicy", webViewConfig.getCompanyPolicy());
        return ApiResult.success(res);

    }

    @ApiOperation("系统推送消息数据列表")
    @GetMapping("system/msg/list")
    public ApiResult<PageResult<SystemMsgResult>> systemMsgList(HttpServletRequest request,
                                                                @RequestParam(defaultValue = "1") int pageNo,
                                                                @RequestParam(defaultValue = "10") int pageSize,
                                                                @RequestParam @ApiParam("1-系统 2-其他 3-广场 4-交易评价 5个人消息") Integer type) {

        Function<MsgQueryParams, PageResult<SystemMsgResult>> instance = componentFactory.getSystemMsgInstance(SystemMsgEnum.getByType(type));
        PageResult<SystemMsgResult> res = instance.apply(new MsgQueryParams(pageNo, pageSize, getId(request)));
        return ApiResult.success(res);
    }

    @ApiOperation("app版本信息")
    @GetMapping("version")
    public ApiResult<TAppVersion> appVersion(@RequestParam(required = false) String type) {
        TAppVersion version = versionMapper.selectOne(new LambdaQueryWrapper<TAppVersion>()
                .eq(TAppVersion::getStatus, CommonStatus.NORMAL.getType()).
                        eq(StringUtils.isNotBlank(type), TAppVersion::getAppType, type)
                .orderByDesc(TAppVersion::getCreateTime)
                .last(" limit 1 "));
        return ApiResult.success(version);
    }

    @ApiOperation("app首页推荐用户列表")
    @GetMapping("recommendMemberList")
    public ApiResult<PageResult<RecommendMemberDTO>> recommendMemberList(@RequestParam(defaultValue = "1") int pageNo,
                                                                         @RequestParam(defaultValue = "10") int pageSize,
                                                                         @ApiParam("智能排序 0 最新 暂时只支持最新排序") @RequestParam(required = false) String auto,
                                                                         @ApiParam("性别过滤 0女 1 男") @RequestParam(required = false) String gender,
                                                                         @ApiParam("年龄筛选  传区间最大值") @RequestParam(required = false) Integer age


    ) {
        return ApiResult.success(memberService.getRecommendMemberList(pageNo, pageSize, auto, gender, age));
    }



}
